# -*-coding:utf-8-*-
import os
import datetime, time
from PIL import Image
from PIL import ImageEnhance
import pytesseract, urllib.request
import pymssql
from LBT.Resource.BaseAtt import BaseAtt
import random, xlrd, xlwt,numpy as np
from xlutils.copy import copy
import pandas as pd


class tools(BaseAtt):
    """
    通用的工具类,处理页面外的所有操作
    """

    # 截图函数
    def insert_img(self, driver, projectName, file_name, file):
        """
        截图函数
        :param driver:驱动
        :param projectName:项目名
        :param file_name: 文件名
        :param file:当前获取文件路径的文件名
        :return:
        """
        base_dir = os.path.dirname(os.path.dirname(file))
        base_dir = str(base_dir)
        base_dir = base_dir.replace('/', '\\')
        base = base_dir.split('test_case')[0]
        file_path = base + "\\Result\\image\\" + file_name
        driver.get_screenshot_as_file(file_path)
        return file_path

    def getCurrentTime(self):
        '''获取当前时间字符串函数'''
        dateCurrent = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')  # 现在
        return dateCurrent

    def getTimintInfo(self):
        '''获取一个小时后的时间'''
        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time() + 60 * 60))

    def writeErrorLog(self, errorMsg):
        '''
        写入错误日志
        :param errorMsg:
        :return:
        '''
        errorMsg = self.getCurrentTime() + '\n' + errorMsg + '\n'
        try:
            f = open("D:/logs/seleniumError.txt", 'a+')
        except Exception as e:
            print("File is not found.")
            os.makedirs("D:/logs/")
            f = open("D:/logs/seleniumError.txt", 'a+')
        f.write(errorMsg)

    def printPageSource(self, dr, sourcename):
        '''
        #获取当前页面的源文件
        :param dr:
        :param sourcename:
        :return:
        '''
        print(dr.page_source)
        sourcename = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "..")) + '//FunctionClass//' + sourcename + '.html'
        if (os.path.exists(sourcename)):
            os.remove(sourcename)
        f = open(sourcename, 'a+')
        f.write(dr.page_source)
        return sourcename

    def selectlbt(self, sql):
        '''连接乐贝通数据库，执行查询操作'''
        # server    数据库服务器名称或IP
        # user      用户名
        # password  密码
        # database  数据库名称
        time.sleep(3)
        conn = pymssql.connect(self.sql_ip, self.sql_user, self.sql_pass, self.sql_dbname)
        cursor = conn.cursor()
        # 查询操作
        cursor.execute(sql)
        row = cursor.fetchone()
        text = ''
        while row:
            print("查询结果为：%s" % (row[0]))
            text += str(row[0])
            row = cursor.fetchone()
        # 也可以使用for循环来迭代查询结果
        # for row in cursor:
        #     print("ID=%d, Name=%s" % (row[0], row[1]))
        # 关闭连接
        conn.close()
        return text
    def selectlbtmutilcolumn(self, sql):
        '''连接乐贝通数据库，执行查询操作'''
        # server    数据库服务器名称或IP
        # user      用户名
        # password  密码
        # database  数据库名称
        time.sleep(3)
        conn = pymssql.connect(self.sql_ip, self.sql_user, self.sql_pass, self.sql_dbname)
        cursor = conn.cursor()
        # 查询操作
        cursor.execute(sql)
        row = cursor.fetchall()
        # 关闭连接
        conn.close()
        return row

    def deleteAndUpdatelbt(self, sql):
        '''连接乐贝通数据库，执行删除操作，慎用！！！！！！！！！'''
        # server    数据库服务器名称或IP
        # user      用户名
        # password  密码
        # database  数据库名称
        conn = pymssql.connect(self.sql_ip, self.sql_user, self.sql_pass, self.sql_dbname)
        cursor = conn.cursor()
        # 删除和修改操作操作
        cursor.execute(sql)
        conn.commit()
        # 关闭连接
        conn.close()
        return True

    def yanzhengma(self, dr, imageelement):
        '''
        根据传入的对象元素，获取元素验证码的内容，并转成文字，
        此为原始转换，不去除空格，对于相似度高的也不能准确识别。比如Z和2
        :param imageelement:
        :return:
        '''
        if (os.path.exists("E://aa.png")):
            os.remove("E://aa.png")
        if (os.path.exists("E://frame4.png")):
            os.remove("E://frame4.png")
        if (os.path.exists("E://image_code.png")):
            os.remove("E://image_code.png")
        dr.save_screenshot("E://aa.png")
        time.sleep(1)
        size1 = imageelement.size
        print(size1)
        location1 = imageelement.location_once_scrolled_into_view
        print(location1)
        coderange = (int(location1['x']), int(location1['y']), int(location1['x'] + size1['width']),
                     int(location1['y'] + size1['height']))  # 写成我们需要截取的位置坐标
        i = Image.open(r"E:\aa.png")  # 打开截图
        frame4 = i.crop(coderange)  # 使用Image的crop函数，从截图中再次截取我们需要的区域
        frame4.save(r"E:\frame4.png")
        i2 = Image.open(r"E:\frame4.png")
        imgry = i2.convert('L')  # 图像加强，二值化，PIL中有九种不同模式。分别为1，L，P，RGB，RGBA，CMYK，YCbCr，I，F。L为灰度图像
        sharpness = ImageEnhance.Contrast(imgry)  # 对比度增强
        i3 = sharpness.enhance(3.0)  # 3.0为图像的饱和度
        i3.save("E:\\image_code.png")
        i4 = Image.open("E:\\image_code.png")
        text = pytesseract.image_to_string(i4).strip()  # 使用image_to_string识别验证码
        print(text)  # 调试用，查看验证码识别是否成功
        text = text.strip().replace(" ", "")
        print("去掉空格后效果：" + text)
        return text

    def downloadimg(self, img_url, file_path, file_name):
        """
        跟进传入的url地址和文件名，存放
        :param img_url: 图片下载路径
        :param file_path: 文件夹路径
        :param file_name: 文件名,注意不要后缀名，后缀是自动获取的
        :return:
        """
        try:
            # 是否有这个路径
            if not os.path.exists(file_path):
                # 创建路径
                os.makedirs(file_path)
                # 获得图片后缀
            file_suffix = os.path.splitext(img_url)[1]
            # 拼接图片名（包含路径）
            filename = '{}{}{}{}'.format(file_path, os.sep, file_name, file_suffix)
            # 下载图片，并保存到文件夹中
            urllib.request.urlretrieve(img_url, filename=filename)

        except IOError as e:
            print("IOError")
        except Exception as e:
            raise e

    def getDir(self, file, count):
        """
        根据传入的文件及次数，查找该文件/文件夹，（级别为count）父级目录路径
        :param file:文件名
        :param count:上级查找次数
        :return:
        """
        for i in range(count):
            file = os.path.dirname(os.path.realpath(file))
            i += 1
        return file

    def checkisChineseWord(self, word):
        """
        检查是否是中文
        :param word:
        :return:
        """
        for ch in word:
            if '\u4e00' <= ch <= '\u9fff':
                return True
        return False

    def uploadImg(self, count, file, imgname="beautiful.jpg"):
        """
        上传图片功能
        :param count:父级目录级别次数
        :param file:文件__file__
        :param imgname:图片名，默认为beautiful.jpg
        :return:
        """
        resourcepath = self.getDir(file, count) + "\\Resource\\"
        newimgpath = resourcepath + imgname
        os.system(resourcepath + "openimg.exe  " + newimgpath)
        time.sleep(5)

    def calculate(self, image1, image2):
        g = image1.histogram()
        s = image2.histogram()
        assert len(g) == len(s), "error"

        data = []

        for index in range(0, len(g)):
            if g[index] != s[index]:
                data.append(1 - abs(g[index] - s[index]) / max(g[index], s[index]))
            else:
                data.append(1)

        return sum(data) / len(g)

    def split_image(self, image, part_size):
        pw, ph = part_size
        w, h = image.size

        sub_image_list = []

        assert w % pw == h % ph == 0, "error"

        for i in range(0, w, pw):
            for j in range(0, h, ph):
                sub_image = image.crop((i, j, i + pw, j + ph)).copy()
                sub_image_list.append(sub_image)

        return sub_image_list

    def compare_image(self, file_image1, file_image2, size=(256, 256), part_size=(64, 64)):
        '''
        'file_image1'和'file_image2'是传入的文件路径
         可以通过'Image.open(path)'创建'image1' 和 'image2' Image 对象.
         'size' 重新将 image 对象的尺寸进行重置，默认大小为256 * 256 .
         'part_size' 定义了分割图片的大小.默认大小为64*64 .
         返回值是 'image1' 和 'image2'对比后的相似度，相似度越高，图片越接近，达到1.0说明图片完全相同。
        '''

        image1 = Image.open(file_image1)
        image2 = Image.open(file_image2)

        img1 = image1.resize(size).convert("RGB")
        sub_image1 = self.split_image(img1, part_size)

        img2 = image2.resize(size).convert("RGB")
        sub_image2 = self.split_image(img2, part_size)

        sub_data = 0
        for im1, im2 in zip(sub_image1, sub_image2):
            sub_data += self.calculate(im1, im2)

        x = size[0] / part_size[0]
        y = size[1] / part_size[1]

        pre = round((sub_data / (x * y)), 6)
        return pre

    def deleteAllFiles(self, filePath):
        """
        删除指定路径下所有文件及文件夹
        :param filePath: 目录
        :return:
        """
        ls = os.listdir(filePath)
        for i in ls:
            c_path = os.path.join(filePath, i)
            if os.path.isdir(c_path):
                self.deleteAllFiles(c_path)
            else:
                os.remove(c_path)

    def getRandomWithDateTime(self, num):
        """
        根据时间获取一个随机数
        :param num 随机数的位数
        :return: 随机数（str）
        """
        for i in range(0, num):
            nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S");
            randomNum = random.randint(0, 99);
            if randomNum <= num:
                randomNum = str(0) + str(randomNum);
            uniqueNum = str(nowTime) + str(randomNum);
            return uniqueNum

    def getRandomStr(self, num):
        """
        获取一个随机数
        :param num 随机数的位数
        :return: 随机数（str）
        """
        # 定义一个种子，从这里面随机拿出一个值，可以是字母
        seeds = "1234567890"
        # 定义一个空列表，每次循环，将拿到的值，加入列表
        random_str = []
        # choice函数：每次从seeds拿一个值，加入列表
        for i in range(num):
            random_str.append(random.choice(seeds))
        # 将列表里的值，变成四位字符串
        return "".join(random_str)

    def writeExcle(self, file, infos, sheetnum=0):
        """
        向指定文件的指定sheet页，写入指定内容
        :param file: 文件地址
        :param infos: list[dict],dict包含（row行、col列、info内容、格式）
        :param sheetnum: 第几个sheet
        :return:
        """
        workbook = xlrd.open_workbook(file)
        workbooknew = copy(workbook)
        sheet = workbooknew.get_sheet(sheetnum)
        for info in infos:
            sheet.write(info['row'], info['col'], label=info['info'])
        workbooknew.save(file)

    def readExcle(self, file, sheetnum=0):
        """
        根据文件名和sheetnum，返回excel内容,如果是目录就读看到的第一个文件，如果是文件就读文件
        :param file:如果是目录就读看到的第一个文件，如果是文件就读文件
        :param sheetnum:
        :return:
        """
        # 等待5秒，文件可能会处于下载中
        time.sleep(5)
        if os.path.isdir(file):
            file = self.getDirFiles(file)[0]
        elif os.path.isfile(file):
            print(file)
        else:
            raise Exception(file + "：不是文件也不是目录")
        try:
            workbook = xlrd.open_workbook(file)
            sheet = workbook.sheet_by_index(sheetnum)
            row = sheet.nrows
            list = []
            for i in range(row):
                list.append(sheet.row_values(i))
                i += 1
            return list
        except Exception:
            #嘗試html格式
            data = pd.read_html(file)[0]
            data=np.array(data)
            data=data.tolist()
            return data

    def getDirFiles(self, dir, list_name=[],ischild=False):
        """
        获取目录下所有文件名
        :param dir:目录
        :param list_name:列表默认为空
        :return:
        """
        if not ischild:
            list_name=[]
        for file in os.listdir(dir):
            file_path = os.path.join(dir, file)
            if os.path.isdir(file_path):
                list_name += self.getDirFiles(file_path, list_name,ischild=True)
            elif os.path.isfile(file_path):
                list_name.append(file_path)
        returnlist=list_name
        return returnlist